import { Injectable, Logger, NotFoundException } from '@nestjs/common';
import { DatabaseService } from './database.service';
import { HeliusService } from './helius.service';
import { PrettyAddressService } from './pretty-address.service';
import { BondingCurveService } from './bonding-curve.service';
import { CreateTokenDto, UpdateTokenDto } from '../dto/token.dto';
import type { Token, Prisma } from '@prisma/client';
import {
  Keypair,
  SystemProgram,
  Transaction,
  PublicKey,
  sendAndConfirmTransaction,
} from '@solana/web3.js';
import {
  createInitializeMintInstruction,
  createMintToInstruction,
  createAssociatedTokenAccountInstruction,
  getAssociatedTokenAddress,
  MINT_SIZE,
  TOKEN_PROGRAM_ID,
  getMinimumBalanceForRentExemptMint,
  ASSOCIATED_TOKEN_PROGRAM_ID,
  createSetAuthorityInstruction,
  AuthorityType,
} from '@solana/spl-token';
import {
  createV1,
  TokenStandard,
  mplTokenMetadata,
} from '@metaplex-foundation/mpl-token-metadata';
import {
  createUmi,
  keypairIdentity,
  publicKey,
  generateSigner,
  createSignerFromKeypair,
  Umi,
} from '@metaplex-foundation/umi';
import { createUmi as createUmiWithDefaults } from '@metaplex-foundation/umi-bundle-defaults';
import * as fs from 'fs';
import * as path from 'path';

@Injectable()
export class TokenService {
  private readonly logger = new Logger(TokenService.name);

  constructor(
    private readonly databaseService: DatabaseService,
    private readonly heliusService: HeliusService,
    private readonly prettyAddressService: PrettyAddressService,
    private readonly bondingCurveService: BondingCurveService,
  ) {}

  /**
   * 加载测试钱包（仅用于开发环境）
   */
  private loadTestWallet(): Keypair {
    try {
      const walletPath = path.join(
        process.cwd(),
        'test-wallet-1754098590485.json',
      );
      const walletData = JSON.parse(fs.readFileSync(walletPath, 'utf8'));
      return Keypair.fromSecretKey(new Uint8Array(walletData.secretKey));
    } catch (error) {
      this.logger.error('Failed to load test wallet:', error);
      // 如果加载失败，生成一个新的测试钱包
      return Keypair.generate();
    }
  }

  async createToken(data: CreateTokenDto): Promise<Token> {
    const startTime = Date.now();
    try {
      this.logger.log(
        'Creating new token with data:',
        JSON.stringify(data, null, 2),
      );

      // 验证支付签名（如果提供了）
      const paymentStart = Date.now();
      if (data.paymentSignature) {
        await this.verifyPaymentSignature(data.paymentSignature, data.creator);
        this.logger.log(`Payment verification took ${Date.now() - paymentStart}ms`);
      } else if (process.env.NODE_ENV === 'production') {
        throw new Error(
          'Payment signature is required in production environment',
        );
      } else {
        this.logger.warn(
          'Skipping payment verification in development environment',
        );
      }

      let mintKeypair: Keypair;

      // 如果启用了靓号地址生成
      const prettyAddressStart = Date.now();
      if (
        data.enablePrettyAddress &&
        (data.prettyPrefix || data.prettySuffix)
      ) {
        this.logger.log('Generating pretty address with config:', {
          prefix: data.prettyPrefix,
          suffix: data.prettySuffix,
          caseSensitive: data.caseSensitive,
          threads: data.threads,
        });

        const result = await this.prettyAddressService.generatePrettyAddress({
          prefix: data.prettyPrefix || '',
          suffix: data.prettySuffix || '',
          caseSensitive: data.caseSensitive || false,
          threads: data.threads || 1,
        });
        mintKeypair = Keypair.fromSecretKey(new Uint8Array(result.secretKey));

        this.logger.log(
          'Generated pretty mint address:',
          mintKeypair.publicKey.toString(),
        );
        this.logger.log(`Pretty address generation took ${Date.now() - prettyAddressStart}ms`);
      } else {
        // 生成随机 mint 地址
        mintKeypair = Keypair.generate();
        this.logger.log(
          'Generated random mint address:',
          mintKeypair.publicKey.toString(),
        );
        this.logger.log(`Random address generation took ${Date.now() - prettyAddressStart}ms`);
      }

      // 检查是否需要通过联合曲线创建代币
      if (data.isBondingCurve) {
        this.logger.log('Creating token with bonding curve...');
        
        // 为联合曲线创建获取创建者密钥
        let creatorKeypair: Keypair;
        if (process.env.NODE_ENV === 'development') {
          // 在开发环境中使用测试钱包作为创建者
          creatorKeypair = this.loadTestWallet();
          this.logger.log('Using test wallet as bonding curve creator:', creatorKeypair.publicKey.toString());
        } else {
          // 在生产环境中，需要从paymentSignature验证中获取创建者密钥
          throw new Error('Production bonding curve creation requires wallet integration');
        }

        try {
          const bondingResult = await this.bondingCurveService.createTokenWithBondingCurve(
            data.name,
            data.symbol,
            data.image || '',
            creatorKeypair
          );

          // 使用联合曲线生成的mint地址
          // 创建一个新的Keypair对象来保存公钥
          const tempKeypair = Keypair.generate();
          Object.defineProperty(tempKeypair, 'publicKey', {
            value: bondingResult.tokenMint,
            writable: false,
            enumerable: true,
            configurable: false
          });
          mintKeypair = tempKeypair;

          this.logger.log('Bonding curve token created successfully:', bondingResult.tokenMint.toString());

          // 保存到数据库
          const token = await this.databaseService.token.create({
            data: {
              mint: bondingResult.tokenMint.toString(),
              name: data.name,
              symbol: data.symbol,
              description: data.description,
              decimals: data.decimals,
              supply: data.supply,
              creator: data.creator,
              image: data.image,
              isPrettyAddress: data.enablePrettyAddress || false,
              prettyPrefix: data.prettyPrefix,
              prettySuffix: data.prettySuffix,
              isBondingCurve: true,
              website: data.website,
              twitter: data.twitter,
              telegram: data.telegram,
              discord: data.discord,
              mintAuthority: data.revokeMintAuthority ? null : data.creator,
              freezeAuthority: data.revokeFreezeAuthority ? null : data.creator,
              updateAuthority: data.creator,
              isMintRevoked: data.revokeMintAuthority || false,
              isFreezeRevoked: data.revokeFreezeAuthority || false,
              isUpdateRevoked: data.revokeUpdateAuthority || false,
              isActive: true,
            },
          });

          this.logger.log('Bonding curve token saved to database with ID:', token.id);
          this.logger.log(`Total bonding curve token creation took ${Date.now() - startTime}ms`);

          return token;
        } catch (error) {
          this.logger.error('Failed to create bonding curve token:', error);
          throw new Error(`Failed to create bonding curve token: ${error.message}`);
        }
      }

      // 获取 Solana 连接
      const connection = await this.heliusService.getConnection();

      // 在开发环境中使用测试钱包作为 payer
      let payerKeypair: Keypair;
      if (process.env.NODE_ENV === 'development') {
        payerKeypair = this.loadTestWallet();
        this.logger.log(
          'Using test wallet as payer:',
          payerKeypair.publicKey.toString(),
        );
      } else {
        // 在生产环境中，这需要不同的处理方式
        throw new Error(
          'Production token creation not implemented. Use frontend wallet integration.',
        );
      }

      // 创建代币的链上交易（包含元数据创建）
      const transaction = new Transaction();

      // 1. 创建 mint 账户所需的租金
      const mintRent = await getMinimumBalanceForRentExemptMint(connection);

      // 2. 创建 mint 账户指令
      transaction.add(
        SystemProgram.createAccount({
          fromPubkey: payerKeypair.publicKey,
          newAccountPubkey: mintKeypair.publicKey,
          space: MINT_SIZE,
          lamports: mintRent,
          programId: TOKEN_PROGRAM_ID,
        }),
      );

      // 3. 初始化 mint 指令 - 先设置后端为所有权限持有者
      const creatorPublicKey = new PublicKey(data.creator);
      transaction.add(
        createInitializeMintInstruction(
          mintKeypair.publicKey,
          data.decimals,
          payerKeypair.publicKey, // mint authority - 后端钱包
          payerKeypair.publicKey, // freeze authority - 后端钱包
        ),
      );

      // 4. 创建创建者的代币账户（用于接收铸造的代币）
      const creatorTokenAccount = await getAssociatedTokenAddress(
        mintKeypair.publicKey,
        creatorPublicKey,
      );

      this.logger.log('Creator token account:', creatorTokenAccount.toString());

      // 5. 添加创建关联代币账户指令
      transaction.add(
        createAssociatedTokenAccountInstruction(
          payerKeypair.publicKey, // payer
          creatorTokenAccount, // ata
          creatorPublicKey, // owner
          mintKeypair.publicKey, // mint
        ),
      );

      // 6. 添加铸造指令 - 将供应量铸造到创建者账户
      const mintAmount = BigInt(data.supply);
      this.logger.log(
        `Minting ${data.supply} tokens (${mintAmount.toString()} base units) to creator`,
      );

      transaction.add(
        createMintToInstruction(
          mintKeypair.publicKey, // mint
          creatorTokenAccount, // destination
          payerKeypair.publicKey, // authority
          mintAmount, // amount
        ),
      );

      // 7. 添加元数据创建指令到同一个交易中
      await this.addMetadataInstructionsToTransaction(
        transaction,
        mintKeypair,
        payerKeypair,
        data,
        connection,
      );

      // 发送第一个交易（创建代币、铸造）
      const transactionStart = Date.now();
      this.logger.log('Sending transaction to create token and mint...');
      const signature = await sendAndConfirmTransaction(
        connection,
        transaction,
        [payerKeypair, mintKeypair],
        {
          commitment: 'confirmed', // 使用 confirmed 而不是 finalized 来加快速度
          skipPreflight: false,
          maxRetries: 3, // 增加重试次数
          preflightCommitment: 'confirmed',
        },
      );

      this.logger.log(
        'Token created and minted successfully. Transaction signature:',
        signature,
      );
      this.logger.log(`Token creation transaction took ${Date.now() - transactionStart}ms`);

      // 创建 Metaplex 元数据（在权限转移之前）
      // 使用优化后的元数据创建方法
      let metadataCreated = false;
      if (true) { // 重新启用以测试优化
        try {
          this.logger.log('Creating Metaplex metadata...');
          const metadataStart = Date.now();
          await this.createMetadataWithTimeout(
            mintKeypair,
            payerKeypair,
            data,
            connection,
          );
          this.logger.log('Metaplex metadata created successfully');
          this.logger.log(`Metadata creation took ${Date.now() - metadataStart}ms`);
          metadataCreated = true;
        } catch (metadataError) {
          this.logger.warn(
            'Failed to create metadata, but token was created successfully:',
            metadataError,
          );
          // 元数据创建失败不应该影响代币的创建
        }
      } else {
        this.logger.log('Metadata creation is disabled to avoid timeout issues');
        this.logger.log('Token will be created without metadata for faster response');
      }

      // 创建第二个交易用于权限转移
      const authorityTransaction = new Transaction();

      // 7. 根据设置决定mint authority的最终状态
      if (data.revokeMintAuthority) {
        this.logger.log('Revoking mint authority...');
        authorityTransaction.add(
          createSetAuthorityInstruction(
            mintKeypair.publicKey, // mint
            payerKeypair.publicKey, // current authority (后端钱包)
            AuthorityType.MintTokens, // authority type
            null, // new authority (null = revoke)
          ),
        );
      } else {
        this.logger.log('Transferring mint authority to creator...');
        authorityTransaction.add(
          createSetAuthorityInstruction(
            mintKeypair.publicKey, // mint
            payerKeypair.publicKey, // current authority
            AuthorityType.MintTokens, // authority type
            creatorPublicKey, // new authority
          ),
        );
      }

      // 8. 根据设置决定freeze authority的最终状态
      if (data.revokeFreezeAuthority) {
        this.logger.log('Revoking freeze authority...');
        authorityTransaction.add(
          createSetAuthorityInstruction(
            mintKeypair.publicKey, // mint
            payerKeypair.publicKey, // current authority (后端钱包)
            AuthorityType.FreezeAccount, // authority type
            null, // new authority (null = revoke)
          ),
        );
      } else {
        this.logger.log('Transferring freeze authority to creator...');
        authorityTransaction.add(
          createSetAuthorityInstruction(
            mintKeypair.publicKey, // mint
            payerKeypair.publicKey, // current authority
            AuthorityType.FreezeAccount, // authority type
            creatorPublicKey, // new authority
          ),
        );
      }

      // 发送权限转移交易
      if (authorityTransaction.instructions.length > 0) {
        this.logger.log('Sending authority transfer transaction...');
        const authorityStart = Date.now();
        const authoritySignature = await sendAndConfirmTransaction(
          connection,
          authorityTransaction,
          [payerKeypair],
          {
            commitment: 'confirmed', // 使用更快的确认级别
            skipPreflight: false,
            maxRetries: 3,
            preflightCommitment: 'confirmed',
          },
        );

        this.logger.log(
          'Authority transfer completed. Transaction signature:',
          authoritySignature,
        );
        this.logger.log(`Authority transfer took ${Date.now() - authorityStart}ms`);
      } else {
        this.logger.log('No authority transfer needed');
      }

      // 保存到数据库
      const dbStart = Date.now();
      const token = await this.databaseService.token.create({
        data: {
          mint: mintKeypair.publicKey.toString(),
          name: data.name,
          symbol: data.symbol,
          description: data.description,
          decimals: data.decimals,
          supply: data.supply,
          creator: data.creator,
          image: data.image,
          isPrettyAddress: data.enablePrettyAddress || false,
          prettyPrefix: data.prettyPrefix,
          prettySuffix: data.prettySuffix,
          isBondingCurve: data.isBondingCurve || false,
          website: data.website,
          twitter: data.twitter,
          telegram: data.telegram,
          discord: data.discord,
          mintAuthority: data.revokeMintAuthority ? null : data.creator,
          freezeAuthority: data.revokeFreezeAuthority ? null : data.creator,
          updateAuthority: data.creator, // Update authority 由 Metaplex 处理
          isMintRevoked: data.revokeMintAuthority || false,
          isFreezeRevoked: data.revokeFreezeAuthority || false,
          isUpdateRevoked: data.revokeUpdateAuthority || false,
          isActive: true,
        },
      });

      this.logger.log('Token saved to database with ID:', token.id);
      this.logger.log(`Database save took ${Date.now() - dbStart}ms`);

      // 为新创建的代币设置初始价格
      try {
        const priceStart = Date.now();
        const updatedToken = await this.updateTokenPrice(token.mint);
        this.logger.log(
          `Initial price set for token ${token.symbol}: $${updatedToken.price}`,
        );
        this.logger.log(`Price update took ${Date.now() - priceStart}ms`);
        this.logger.log(`Total token creation time: ${Date.now() - startTime}ms`);
        return updatedToken;
      } catch (priceError) {
        this.logger.warn(
          'Failed to set initial price, returning token without price:',
          priceError,
        );
        this.logger.log(`Total token creation time: ${Date.now() - startTime}ms`);
        return token;
      }
    } catch (error) {
      this.logger.error('Failed to create token:', error);
      this.logger.log(`Total time before error: ${Date.now() - startTime}ms`);
      throw error;
    }
  }

  async getTokenByMint(mint: string): Promise<Token | null> {
    try {
      return await this.databaseService.token.findUnique({
        where: { mint },
      });
    } catch (error) {
      this.logger.error(`Failed to get token by mint ${mint}:`, error);
      throw error;
    }
  }

  async getTokenById(id: string): Promise<Token> {
    try {
      const token = await this.databaseService.token.findUnique({
        where: { id },
      });

      if (!token) {
        throw new NotFoundException(`Token with ID ${id} not found`);
      }

      return token;
    } catch (error) {
      this.logger.error(`Failed to get token by ID ${id}:`, error);
      throw error;
    }
  }

  async getTokens(options?: {
    page?: number;
    limit?: number;
    creator?: string;
    isActive?: boolean;
    search?: string;
    orderBy?: 'createdAt' | 'marketCap' | 'price' | 'holders';
    order?: 'asc' | 'desc';
  }): Promise<{
    tokens: Token[];
    total: number;
    page: number;
    limit: number;
    totalPages: number;
  }> {
    try {
      const page = options?.page || 1;
      const limit = options?.limit || 20;
      const skip = (page - 1) * limit;

      const where: Prisma.TokenWhereInput = {};

      if (options?.creator) {
        where.creator = options.creator;
      }

      if (options?.isActive !== undefined) {
        where.isActive = options.isActive;
      }

      if (options?.search) {
        where.OR = [
          { name: { contains: options.search, mode: 'insensitive' } },
          { symbol: { contains: options.search, mode: 'insensitive' } },
          { description: { contains: options.search, mode: 'insensitive' } },
        ];
      }

      // 处理排序
      const orderBy = options?.orderBy || 'createdAt';
      const order = options?.order || 'desc';

      const orderByClause: Prisma.TokenOrderByWithRelationInput = {};
      orderByClause[orderBy] = order;

      const [tokens, total] = await Promise.all([
        this.databaseService.token.findMany({
          where,
          skip,
          take: limit,
          orderBy: orderByClause,
        }),
        this.databaseService.token.count({ where }),
      ]);

      return {
        tokens,
        total,
        page,
        limit,
        totalPages: Math.ceil(total / limit),
      };
    } catch (error) {
      this.logger.error('Failed to get tokens:', error);
      throw error;
    }
  }

  async getTrendingTokens(limit = 10): Promise<Token[]> {
    try {
      return await this.databaseService.token.findMany({
        where: { isActive: true },
        orderBy: [
          { marketCap: 'desc' },
          { holders: 'desc' },
          { createdAt: 'desc' },
        ],
        take: limit,
      });
    } catch (error) {
      this.logger.error('Failed to get trending tokens:', error);
      throw error;
    }
  }

  async searchTokens(query: string, limit = 20): Promise<Token[]> {
    try {
      return await this.databaseService.token.findMany({
        where: {
          isActive: true,
          OR: [
            { name: { contains: query, mode: 'insensitive' } },
            { symbol: { contains: query, mode: 'insensitive' } },
            { description: { contains: query, mode: 'insensitive' } },
          ],
        },
        orderBy: { createdAt: 'desc' },
        take: limit,
      });
    } catch (error) {
      this.logger.error('Failed to search tokens:', error);
      throw error;
    }
  }

  async updateToken(mint: string, data: UpdateTokenDto): Promise<Token> {
    try {
      const token = await this.databaseService.token.update({
        where: { mint },
        data: {
          ...data,
          updatedAt: new Date(),
        },
      });

      this.logger.log(`Token ${mint} updated successfully`);
      return token;
    } catch (error) {
      this.logger.error(`Failed to update token ${mint}:`, error);
      throw error;
    }
  }

  async deleteToken(mint: string): Promise<void> {
    try {
      await this.databaseService.token.delete({
        where: { mint },
      });

      this.logger.log(`Token ${mint} deleted successfully`);
    } catch (error) {
      this.logger.error('Failed to delete token:', error);
      throw error;
    }
  }

  async syncTokenMetadata(mint: string): Promise<Token> {
    // TODO: 实现从链上同步元数据的逻辑
    this.logger.log(`Syncing metadata for token ${mint}`);
    return this.getTokenByMint(mint);
  }

  async updateTokenPrice(mint: string): Promise<Token> {
    try {
      this.logger.log(`Updating price and market data for token ${mint}`);

      const token = await this.getTokenByMint(mint);

      if (!token) {
        throw new Error(`Token ${mint} not found`);
      }

      let price: number;
      let marketCap: number;
      
      // 如果是联合曲线代币，从联合曲线获取真实价格和市值
      if (token.isBondingCurve) {
        try {
          const tokenMint = new PublicKey(mint);
          const tokenInfo = await this.bondingCurveService.getTokenInfo(tokenMint);
          price = tokenInfo.price;
          marketCap = tokenInfo.marketCap || 0; // 使用联合曲线返回的市值
          
          // 更新数据库中的毕业状态
          if (tokenInfo.isGraduated !== token.isGraduated) {
            await this.databaseService.token.update({
              where: { mint },
              data: { isGraduated: tokenInfo.isGraduated }
            });
            token.isGraduated = tokenInfo.isGraduated;
          }
          
          this.logger.log(`Got bonding curve data for ${token.symbol}: Price=$${price}, MarketCap=$${marketCap}, Graduated=${tokenInfo.isGraduated}`);
        } catch (bondingError) {
          this.logger.warn(`Failed to get bonding curve data for ${mint}, using mock values:`, bondingError);
          price = this.generateMockPrice(token);
          marketCap = this.calculateMarketCap(token.supply, price, token.decimals);
        }
      } else {
        // 对于非联合曲线代币，使用模拟价格
        price = this.generateMockPrice(token);
        marketCap = this.calculateMarketCap(token.supply, price, token.decimals);
      }

      // 获取持有者数量
      const holders = await this.getTokenHoldersCount(mint);

      const updatedToken = await this.databaseService.token.update({
        where: { mint },
        data: {
          price,
          marketCap,
          holders,
          updatedAt: new Date(),
        },
      });

      this.logger.log(
        `Updated token ${token.symbol}: Price=$${price}, Market Cap=$${marketCap}, Holders=${holders}`,
      );
      return updatedToken;
    } catch (error) {
      this.logger.error(`Failed to update price for token ${mint}:`, error);
      throw error;
    }
  }

  /**
   * 生成模拟价格（仅用于演示）
   */
  private generateMockPrice(token: Token): number {
    // 基于代币名称和时间生成一个相对稳定但有变化的价格
    const basePrice = 0.001; // 基础价格 $0.001
    const hash = this.simpleHash(token.mint);
    const timeFactor = Math.sin(Date.now() / 1000000) * 0.1 + 1; // 时间因子，造成价格波动
    const randomFactor = (hash % 100) / 100; // 基于mint地址的稳定随机因子

    return Number((basePrice * (1 + randomFactor) * timeFactor).toFixed(6));
  }

  /**
   * 计算市值
   */
  private calculateMarketCap(
    supply: string,
    price: number,
    decimals: number,
  ): number {
    try {
      const supplyNumber = Number(supply);
      const actualSupply = supplyNumber / Math.pow(10, decimals);
      const marketCap = actualSupply * price;
      
      // 对于非常小的市值，使用科学记数法保持精度
      if (marketCap < 1e-6) {
        // 对于极小值，保持完整精度
        return marketCap;
      } else if (marketCap < 0.01) {
        return Number(marketCap.toFixed(12));
      } else if (marketCap < 1) {
        return Number(marketCap.toFixed(8));
      } else {
        return Number(marketCap.toFixed(2));
      }
    } catch (error) {
      this.logger.error('Failed to calculate market cap:', error);
      return 0;
    }
  }

  /**
   * 获取代币的实际持有者数量
   */
  private async getTokenHoldersCount(mint: string): Promise<number> {
    try {
      // 检查是否是联合曲线代币
      const token = await this.databaseService.token.findUnique({
        where: { mint },
        select: { isBondingCurve: true }
      });

      if (token?.isBondingCurve) {
        // 对于联合曲线代币，从联合曲线合约获取持有者信息
        try {
          const tokenMint = new PublicKey(mint);
          const tokenInfo = await this.bondingCurveService.getTokenInfo(tokenMint);
          // 联合曲线代币至少有1个持有者（创建者）
          // 如果有流通供应量，可能有更多持有者
          return Math.max(1, tokenInfo.circulatingSupply > 0 ? 2 : 1);
        } catch (bondingError) {
          this.logger.warn(`Failed to get bonding curve holders for ${mint}:`, bondingError);
          return 1; // 默认至少有创建者
        }
      }

      // 通过 Helius API 获取代币持有者数量
      const response = await this.heliusService.getTokenHolders(mint);
      return response?.length || 0;
    } catch (error) {
      this.logger.warn(`Failed to get holders count for ${mint}:`, error);
      // 如果获取失败，返回一个基于交易数量的模拟值
      return this.generateMockHolders(mint);
    }
  }

  /**
   * 生成模拟持有者数量
   */
  private generateMockHolders(mint: string): number {
    const hash = this.simpleHash(mint);
    // 基于 mint 地址生成 1-50 之间的持有者数量
    return Math.max(1, (hash % 50) + 1);
  }

  /**
   * 批量更新所有代币的价格和市值数据
   */
  async updateAllTokensMarketData(): Promise<void> {
    try {
      this.logger.log('Starting batch update of all token market data...');
      
      // 获取所有活跃代币
      const tokens = await this.databaseService.token.findMany({
        where: { isActive: true },
        select: { mint: true, symbol: true },
      });

      this.logger.log(`Found ${tokens.length} active tokens to update`);

      // 分批处理，避免并发过多
      const batchSize = 5;
      for (let i = 0; i < tokens.length; i += batchSize) {
        const batch = tokens.slice(i, i + batchSize);
        
        await Promise.allSettled(
          batch.map(async (token) => {
            try {
              await this.updateTokenPrice(token.mint);
              this.logger.log(`✅ Updated ${token.symbol}`);
            } catch (error) {
              this.logger.warn(`❌ Failed to update ${token.symbol}:`, error.message);
            }
          })
        );

        // 批次之间稍作停顿
        if (i + batchSize < tokens.length) {
          await new Promise(resolve => setTimeout(resolve, 1000));
        }
      }

      this.logger.log('Batch update completed!');
    } catch (error) {
      this.logger.error('Batch update failed:', error);
      throw error;
    }
  }

  /**
   * 简单哈希函数
   */
  private simpleHash(str: string): number {
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = (hash << 5) - hash + char;
      hash = hash & hash; // 转换为32位整数
    }
    return Math.abs(hash);
  }

  /**
   * 验证支付签名
   */
  private async verifyPaymentSignature(
    signature: string,
    creator: string,
  ): Promise<void> {
    try {
      this.logger.log(
        `Verifying payment signature: ${signature} from ${creator}`,
      );

      const connection = await this.heliusService.getConnection();

      // 获取交易详情
      const transaction = await connection.getTransaction(signature, {
        commitment: 'confirmed',
      });

      if (!transaction) {
        throw new Error('Payment transaction not found');
      }

      // 验证交易状态
      if (transaction.meta?.err) {
        throw new Error('Payment transaction failed');
      }

      // 验证交易的发送者
      const fromPubkey =
        transaction.transaction.message.accountKeys[0].toString();
      if (fromPubkey !== creator) {
        throw new Error('Payment sender does not match creator');
      }

      // 验证接收者是平台钱包
      const platformWallet = '813sZTyqkmUrbcGt1Bbo6dn6oRYC6Mh8og5Uk6EmFMAT';

      // 通过账户余额变化来验证转账
      const accountKeys = transaction.transaction.message.accountKeys;
      let transferAmount = 0;

      // 查找平台钱包在账户列表中的索引
      let platformWalletIndex = -1;
      for (let i = 0; i < accountKeys.length; i++) {
        if (accountKeys[i].toString() === platformWallet) {
          platformWalletIndex = i;
          break;
        }
      }

      if (platformWalletIndex === -1) {
        throw new Error('Platform wallet not found in transaction accounts');
      }

      // 计算平台钱包的余额变化
      const preBalance =
        transaction.meta?.preBalances[platformWalletIndex] || 0;
      const postBalance =
        transaction.meta?.postBalances[platformWalletIndex] || 0;
      transferAmount = postBalance - preBalance;

      this.logger.log(
        `Platform wallet balance change: ${transferAmount} lamports (from ${preBalance} to ${postBalance})`,
      );

      if (transferAmount <= 0) {
        throw new Error('No transfer to platform wallet found in transaction');
      }

      // 验证转账金额是否至少 0.2 SOL (200,000,000 lamports)
      const requiredAmount = 0.2 * 1e9; // 0.2 SOL in lamports
      if (transferAmount < requiredAmount) {
        throw new Error(
          `Insufficient payment amount. Required: ${requiredAmount} lamports, received: ${transferAmount} lamports`,
        );
      }

      this.logger.log(
        `Payment verification successful: ${transferAmount} lamports transferred`,
      );
    } catch (error) {
      this.logger.error('Payment verification failed:', error);
      throw new Error(`Payment verification failed: ${error.message}`);
    }
  }

  /**
   * 添加元数据创建指令到交易中
   * 使用更简单的方法：创建单独的元数据交易
   */
  private async addMetadataInstructionsToTransaction(
    transaction: Transaction,
    mintKeypair: Keypair,
    payerKeypair: Keypair,
    tokenData: CreateTokenDto,
    connection: any,
  ): Promise<void> {
    // 暂时跳过在同一交易中创建元数据
    // 我们将在代币创建后立即创建元数据
    this.logger.log('Metadata will be created in a separate transaction after token creation');
    return;
  }

  /**
   * 使用 UMI 创建元数据（在代币创建后，权限转移前）
   */
  private async createTokenMetadataWithUmi(
    mintKeypair: Keypair,
    payerKeypair: Keypair,
    tokenData: CreateTokenDto,
    connection: any,
  ): Promise<void> {
    try {
      this.logger.log('Creating metadata using UMI...');

      // 添加超时控制
      const timeout = new Promise((_, reject) => {
        setTimeout(() => reject(new Error('Metadata creation timeout after 25 seconds')), 25000);
      });

      const metadataCreation = this.createMetadataWithTimeout(
        mintKeypair, 
        payerKeypair, 
        tokenData, 
        connection
      );

      // 使用 Promise.race 来控制超时
      await Promise.race([metadataCreation, timeout]);

      this.logger.log('Metadata created successfully!');

    } catch (error) {
      this.logger.error('Failed to create metadata with UMI:', error);
      this.logger.warn('Continuing without metadata - token functionality will not be affected');
      // 不抛出错误，让代币创建流程继续
    }
  }

  /**
   * 带超时控制的元数据创建
   */
  private async createMetadataWithTimeout(
    mintKeypair: Keypair,
    payerKeypair: Keypair,
    tokenData: CreateTokenDto,
    connection: any,
  ): Promise<void> {
    // 使用 UMI 创建元数据
    const rpcUrl = connection.rpcEndpoint || 'https://api.devnet.solana.com';
    const umi = createUmiWithDefaults(rpcUrl).use(mplTokenMetadata());

    // 设置支付者为身份
    const payerSigner = createSignerFromKeypair(umi, {
      publicKey: publicKey(payerKeypair.publicKey.toString()),
      secretKey: payerKeypair.secretKey,
    });
    umi.use(keypairIdentity(payerSigner));

    // 创建 mint signer
    const mintSigner = createSignerFromKeypair(umi, {
      publicKey: publicKey(mintKeypair.publicKey.toString()),
      secretKey: mintKeypair.secretKey,
    });

    this.logger.log('Creating metadata for mint:', mintKeypair.publicKey.toString());
    this.logger.log('Update authority will be:', 
      tokenData.revokeUpdateAuthority ? 'revoked' : tokenData.creator);

    // 使用 createV1 创建元数据
    const tx = await createV1(umi, {
      mint: mintSigner,
      authority: payerSigner, // 当前的 mint authority
      name: tokenData.name,
      symbol: tokenData.symbol,
      uri: '', // 可以为空或指向 JSON 元数据文件
      sellerFeeBasisPoints: {
        basisPoints: BigInt(0),
        identifier: '%' as const,
        decimals: 2,
      },
      tokenStandard: TokenStandard.Fungible,
      isMutable: !tokenData.revokeUpdateAuthority, // 根据用户设置决定是否可变
      creators: [
        {
          address: publicKey(tokenData.creator),
          verified: false,
          share: 100,
        },
      ],
    });

    // 发送元数据创建交易，设置较短的超时
    const result = await tx.sendAndConfirm(umi, {
      confirm: { commitment: 'confirmed' },
      send: { 
        skipPreflight: false,
        maxRetries: 3, // 最多重试3次
      },
    });

    this.logger.log('Metadata transaction signature:', result.signature);

    // 权限转移操作（如果失败也不影响主流程）
    try {
      if (tokenData.revokeUpdateAuthority) {
        await this.revokeUpdateAuthority(umi, mintKeypair, payerSigner);
      } else {
        await this.transferUpdateAuthority(umi, mintKeypair, payerSigner, tokenData.creator);
      }
    } catch (authorityError) {
      this.logger.warn('Authority transfer failed but metadata was created:', authorityError);
    }
  }

  /**
   * 撤销更新权限
   */
  private async revokeUpdateAuthority(
    umi: any, 
    mintKeypair: Keypair, 
    currentAuthority: any
  ): Promise<void> {
    try {
      const { updateV1 } = await import('@metaplex-foundation/mpl-token-metadata');
      
      const tx = await updateV1(umi, {
        mint: publicKey(mintKeypair.publicKey.toString()),
        authority: currentAuthority,
        newUpdateAuthority: null, // 撤销权限
      });

      await tx.sendAndConfirm(umi);
      this.logger.log('Update authority revoked successfully');
    } catch (error) {
      this.logger.warn('Failed to revoke update authority:', error);
    }
  }

  /**
   * 转移更新权限给创建者
   */
  private async transferUpdateAuthority(
    umi: any, 
    mintKeypair: Keypair, 
    currentAuthority: any, 
    newAuthority: string
  ): Promise<void> {
    try {
      const { updateV1 } = await import('@metaplex-foundation/mpl-token-metadata');
      
      const tx = await updateV1(umi, {
        mint: publicKey(mintKeypair.publicKey.toString()),
        authority: currentAuthority,
        newUpdateAuthority: publicKey(newAuthority),
      });

      await tx.sendAndConfirm(umi);
      this.logger.log('Update authority transferred to creator successfully');
    } catch (error) {
      this.logger.warn('Failed to transfer update authority:', error);
    }
  }

  /**
   * 获取平台统计数据
   */
  async getPlatformStats(): Promise<{
    totalTokens: number;
    totalVolume: number;
    activeTraders: number;
  }> {
    try {
      this.logger.log('Starting to fetch platform stats...');
      
      // 获取代币总数
      const totalTokens = await this.databaseService.token.count();
      this.logger.log(`Total tokens count: ${totalTokens}`);

      // 获取总交易量 (SOL)
      // 这里假设我们有交易记录表，如果没有则返回计算值
      const allTokens = await this.databaseService.token.findMany({
        select: {
          id: true,
          marketCap: true,
        },
      });
      this.logger.log(`Found ${allTokens.length} tokens for volume calculation`);

      // 基于市值计算总交易量的估算值
      const totalVolume = allTokens.reduce((sum, token) => {
        // 假设交易量约为市值的 10%
        const volume = (token.marketCap || 0) * 0.1;
        return sum + volume;
      }, 0);
      this.logger.log(`Calculated total volume: ${totalVolume}`);

      // 获取活跃交易者数量
      // 这里使用一个基于代币数量的估算值，实际应该基于交易记录
      const activeTraders = Math.floor(totalTokens * 5.6); // 平均每个代币约5-6个交易者
      this.logger.log(`Calculated active traders: ${activeTraders}`);

      const result = {
        totalTokens,
        totalVolume: Math.round(totalVolume * 100) / 100, // 保留两位小数
        activeTraders,
      };

      this.logger.log(`Platform stats result: ${JSON.stringify(result)}`);
      return result;
    } catch (error) {
      this.logger.error('Failed to get platform stats:', error);
      // 返回默认值
      const defaultResult = {
        totalTokens: 0,
        totalVolume: 0,
        activeTraders: 0,
      };
      this.logger.log(`Returning default stats: ${JSON.stringify(defaultResult)}`);
      return defaultResult;
    }
  }

  /**
   * 创建 Metaplex 代币元数据
   * 注意：当前实现暂时禁用，因为需要复杂的权限处理
   */
  private async createTokenMetadata(
    mintKeypair: Keypair,
    payerKeypair: Keypair,
    tokenData: CreateTokenDto,
    connection: any,
  ): Promise<void> {
    this.logger.log('Metadata creation is currently disabled');
    this.logger.log('Token functionality is complete without metadata');
    return;
  }
}
